package com.orange.core.service.oss;

import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.orange.core.config.alicloud.oss.OssProperties;
import com.orange.core.mapper.oss.OssFileMapper;
import com.orange.core.pojo.entity.oss.OssFile;
import com.orange.core.pojo.rsp.oss.OssUploadRsp;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

@Slf4j
@RequiredArgsConstructor
@Service
public class OssFileService extends ServiceImpl<OssFileMapper, OssFile> {

    private final OssProperties ossProperties;
    private final OSS oss;

    @SneakyThrows
    public OssFile getByFilename(String filename) {
        OssFile ossFile = this.lambdaQuery().eq(OssFile::getFilename, filename).one();
        if (ossFile != null) {
            return ossFile.setObject(oss.getObject(ossFile.getBucketName(), ossFile.getFilename()).getObjectContent().readAllBytes());
        }
        return null;
    }

    @SneakyThrows
    public OssFile getByPath(String path) {
        OssFile ossFile = this.lambdaQuery().eq(OssFile::getPath, path).one();
        if (ossFile != null) {
            return ossFile.setObject(oss.getObject(ossFile.getBucketName(), ossFile.getFilename()).getObjectContent().readAllBytes());
        }
        return null;
    }

    /**
     * @param path  url
     * @param angle 拼接参数（旋转，缩小）
     * @return {@link OssFile}
     */
    @SneakyThrows
    public OssFile getByPathFit(String path, String angle) {
        int minSize = 2048;
        OssFile ossFile = this.lambdaQuery().eq(OssFile::getPath, path).one();
        OSSObject obj;
        if (ossFile == null) {
            return null;
        }
        int max = Math.max(ossFile.getWidth(), ossFile.getHeight());
        if (max > minSize) {
            GetObjectRequest request = new GetObjectRequest(ossFile.getBucketName(), ossFile.getFilename());
            String process = StrUtil.format("image/resize,{}_{},m_lfit", ossFile.getWidth() == max ? "w" : "h", minSize);

            if (StrUtil.isNotBlank(angle)) {
                process = StrUtil.format("image/resize,{}_{},m_lfit/rotate,{}", ossFile.getWidth() == max ? "w" : "h", minSize, angle);
            }
            request.setProcess(process);
            obj = oss.getObject(request);
        } else {
            GetObjectRequest request = new GetObjectRequest(ossFile.getBucketName(), ossFile.getFilename());
            if (StrUtil.isNotBlank(angle)) {
                request.setProcess(StrUtil.format("image/rotate,{}", angle));
            }
            obj = oss.getObject(request);
        }

        return ossFile.setObject(obj.getObjectContent().readAllBytes());
    }

    /**
     * @param filename 上传到oss的文件名
     */
    @Transactional
    public OssUploadRsp uploadFile(InputStream inputStream, String filename) {
        String key = String.format("%s_%s", System.currentTimeMillis(), filename);
        return uploadFileSelf(inputStream, key);
    }

    /**
     * @param key 上传到oss的文件名
     */
    @Transactional
    public OssUploadRsp uploadFileSelf(InputStream inputStream, String key) {
        try {
            byte[] bytes = inputStream.readAllBytes();
            oss.putObject(ossProperties.getBucket(), key, new ByteArrayInputStream(bytes));
            OssFile ossFile = new OssFile().setFilename(key)
                    .setPath(String.format("//%s.%s/%s", ossProperties.getBucket(), ossProperties.getEndpoint(), key))
                    .setBucketName(ossProperties.getBucket());
            this.save(ossFile);
            return new OssUploadRsp().setFilename(key).setFilePath(ossFile.getPath());
        } catch (Exception e) {
            log.error("上传文件失败：", e);
            throw new RuntimeException(e);
        }
    }
}
